package com.jsy.common.util;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.util.StringUtils;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Iterator;

public class ImageHelper {

    public static void main(String[] args) {
        //添加水印
//        addWaterMark();
        //对半截取目录下所有图片
//        cutHalfImageFromDir();
        //压缩图片
//        try {
//            commpressPicForScale("H:/book/out/3.png", "H:/book/out/3-1.png",150*1024,10,1000,1500);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        File file = new File("H:/book/water/cut");
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            String filename = files[i].getAbsolutePath();
            System.out.println(filename);
            try {
                commpressPicForScale(filename, filename,100*1024,1,1000,1500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void cutHalfImageFromDir() {
        String path = "H:/book/water";
        File fils = new File(path);
        File files[] = fils.listFiles();
        for (int i = 0; i < files.length; i++) {
            String fileName = files[i].getAbsolutePath();
            if (!files[i].isFile()) {
                continue;
            }
            String name = path + "\\cut\\";
            if (!new File(name).exists()) {
                new File(name).mkdir();
            }
            String name1 = files[i].getName();
            String name2 = name1.substring(0, name1.lastIndexOf("."));
            try {
                cutHalfImage(fileName, name + name2 + "-2.png", name + name2 + "-1.png");
                System.out.println("=========" + i + "==========");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
     * 根据尺寸图片居中裁剪
     */
    public static void cutCenterImage(String src, String dest, int w, int h) throws IOException {
        Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
        InputStream in = new FileInputStream(src);
        ImageReader reader = (ImageReader) iterator.next();
        ImageInputStream iis = ImageIO.createImageInputStream(in);
        reader.setInput(iis, true);
        ImageReadParam param = reader.getDefaultReadParam();
        int imageIndex = 0;
        Rectangle rect = new Rectangle((reader.getWidth(imageIndex) - w) / 2, (reader.getHeight(imageIndex) - h) / 2, w, h);
        param.setSourceRegion(rect);
        BufferedImage bi = reader.read(0, param);
        ImageIO.write(bi, "jpg", new File(dest));

    }

    /*
     * 图片裁剪二分之一
     */
    public static void cutHalfImage(String src, String dest, String dest2) throws IOException {
        Iterator iterator = ImageIO.getImageReadersByFormatName("png");
        ImageReader reader = (ImageReader) iterator.next();
        InputStream in = new FileInputStream(src);
        ImageInputStream iis = ImageIO.createImageInputStream(in);
        reader.setInput(iis, true);
        int imageIndex = 0;
        ImageReadParam param = reader.getDefaultReadParam();
        int width = reader.getWidth(imageIndex);
        int height = reader.getHeight(imageIndex);
        Rectangle rect = new Rectangle(0, 0, width / 2, height);
        param.setSourceRegion(rect);
        BufferedImage bi = reader.read(0, param);
        ImageIO.write(bi, "png", new File(dest));

        Rectangle rect2 = new Rectangle(width / 2, 0, width, height);
        param.setSourceRegion(rect2);
        bi = reader.read(0, param);
        ImageIO.write(bi, "png", new File(dest2));
    }
    /*
     * 图片裁剪通用接口
     */

    public static void cutImage(String src, String dest, int x, int y, int w, int h) throws IOException {
        Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
        ImageReader reader = (ImageReader) iterator.next();
        InputStream in = new FileInputStream(src);
        ImageInputStream iis = ImageIO.createImageInputStream(in);
        reader.setInput(iis, true);
        ImageReadParam param = reader.getDefaultReadParam();
        Rectangle rect = new Rectangle(x, y, w, h);
        param.setSourceRegion(rect);
        BufferedImage bi = reader.read(0, param);
        ImageIO.write(bi, "jpg", new File(dest));

    }

    /*
     * 图片缩放
     */
    public static void zoomImage(String src, String dest, int w, int h) throws Exception {
        double wr = 0, hr = 0;
        File srcFile = new File(src);
        File destFile = new File(dest);
        BufferedImage bufImg = ImageIO.read(srcFile);
        Image Itemp = bufImg.getScaledInstance(w, h, bufImg.SCALE_SMOOTH);
        wr = w * 1.0 / bufImg.getWidth();
        hr = h * 1.0 / bufImg.getHeight();
        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
        Itemp = ato.filter(bufImg, null);
        try {
            ImageIO.write((BufferedImage) Itemp, dest.substring(dest.lastIndexOf(".") + 1), destFile);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    /**
     * 给图片添加水印
     */
    public static void addWaterMark() {

        Color color = new Color(255, 200, 0, 118);   // 水印颜色
        Font font = new Font("微软雅黑", Font.ITALIC, 100);  //水印字体
//        String waterMarkContent="图片来源：http://www.baidu.com/zjq_1314520";
        String waterMarkContent = "我爱你 I LOVE YOU";   //水印内容
        String tarImgPath = "H:\\book\\out\\water.png";  //存储目标路径
        try {
            File file = new File("H:\\book\\out\\0.png");  //原图片
            BufferedImage buImage = ImageIO.read(file);
            int width = buImage.getWidth(); //图片宽
            int height = buImage.getHeight(); //图片高

            //添加水印
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics2D g = bufferedImage.createGraphics();
            g.drawImage(buImage, 0, 0, width, height, null);
            g.setColor(color); //水印颜色
            g.setFont(font); //水印字体

            int x = width - 2 * getWatermarkLength(waterMarkContent, g);  //这是一个计算水印位置的函数，可以根据需求添加
            int y = height - 1 * getWatermarkLength(waterMarkContent, g);
            g.drawString(waterMarkContent, 400, 300); //水印位置
            g.dispose(); //释放资源

            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufferedImage, "png", outImgStream);
            System.out.println("添加水印完成");
            outImgStream.flush();
            outImgStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }

    public static String commpressPicForScale(String srcPath, String desPath,
                                              long desFileSize, double accuracy, int desMaxWidth, int desMaxHeight) {
        if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(srcPath)) {
            return null;
        }
        if (!new File(srcPath).exists()) {
            return null;
        }
        try {
            File srcFile = new File(srcPath);
            long srcFileSize = srcFile.length();
            System.out.println("源图片：" + srcPath + "，大小：" + srcFileSize / 1024
                    + "kb");
            //获取图片信息
            BufferedImage bim = ImageIO.read(srcFile);
            int srcWidth = bim.getWidth();
            int srcHeight = bim.getHeight();

            //先转换成jpg
            Thumbnails.Builder builder = Thumbnails.of(srcFile).outputFormat("jpg");

            // 指定大小（宽或高超出会才会被缩放）
            if (srcWidth > desMaxWidth || srcHeight > desMaxHeight) {
                builder.size(desMaxWidth, desMaxHeight);
            } else {
                //宽高均小，指定原大小
                builder.size(srcWidth, srcHeight);
            }

            // 写入到内存
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节输出流（写入到内存）
            builder.toOutputStream(baos);

            // 递归压缩，直到目标文件大小小于desFileSize
            byte[] bytes = commpressPicCycle(baos.toByteArray(), desFileSize, accuracy);

            // 输出到文件
            File desFile = new File(desPath);
            FileOutputStream fos = new FileOutputStream(desFile);
            fos.write(bytes);
            fos.close();

            System.out.println("目标图片：" + desPath + "，大小" + desFile.length() / 1024 + "kb");
            System.out.println("图片压缩完成！");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return desPath;
    }

    private static byte[] commpressPicCycle(byte[] bytes, long desFileSize, double accuracy) throws IOException {
        // File srcFileJPG = new File(desPath);
        long srcFileSizeJPG = bytes.length;
        // 2、判断大小，如果小于500kb，不压缩；如果大于等于500kb，压缩
        if (srcFileSizeJPG <= desFileSize * 1024) {
            return bytes;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(new ByteArrayInputStream(bytes));
        int srcWdith = bim.getWidth();
        int srcHeigth = bim.getHeight();
        int desWidth = new BigDecimal(srcWdith).multiply(
                new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(srcHeigth).multiply(
                new BigDecimal(accuracy)).intValue();

        ByteArrayOutputStream baos = new ByteArrayOutputStream(); //字节输出流（写入到内存）
        Thumbnails.of(new ByteArrayInputStream(bytes)).size(desWidth, desHeight).outputQuality(accuracy).toOutputStream(baos);
        return commpressPicCycle(baos.toByteArray(), desFileSize, accuracy);
    }

}


